package com.zy.rpc.server;

import com.zy.rpc.common.register.RegistryService;
import com.zy.rpc.common.serviceinfo.ServiceInfo;
import com.zy.rpc.server.cache.LocalServerCache;
import com.zy.rpc.server.config.RpcServerProperties;
import com.zy.rpc.server.transport.RpcServer;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.stereotype.Component;
import com.zy.rpc.server.annotation.RpcService;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * @author zy
 * @date 2023/4/23 16:28
 */

public class RpcServerStart implements BeanPostProcessor, CommandLineRunner {
    /*
    BeanPostProcessor 接口用于在返回给调用者之前修改或替换已实例化的 bean 实例
    CommandLineRunner 接口用于指示在应用程序启动时应运行 用于初始化数据等
    * */


    private RegistryService registryService;

    private RpcServerProperties rpcServerProperties;

    private RpcServer rpcServer;

    public RpcServerStart(RegistryService registryService, RpcServer rpcServer, RpcServerProperties properties) {
        this.registryService = registryService;
        this.rpcServerProperties = properties;
        this.rpcServer = rpcServer;
    }


    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        RpcService rpcService = bean.getClass().getAnnotation(RpcService.class);
        if(rpcService != null){
            String serviceName=rpcService.interfaceType().getName();
            LocalServerCache.cache(serviceName,bean);
            ServiceInfo serviceInfo = null;
            try {
                serviceInfo = ServiceInfo.builder()
                            .serviceName(serviceName)
                            .port(rpcServerProperties.getPort())
                            .address(InetAddress.getLocalHost().getHostAddress())
                            .appName(rpcServerProperties.getAppName())
                            .build();
            } catch (UnknownHostException e) {
                throw new RuntimeException(e);
            }
            try {
                registryService.register(serviceInfo);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return bean;
    }
    @Override
    public void run(String... args)  {
        new Thread(() -> rpcServer.Start(rpcServerProperties.getPort())).start();
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                // 关闭之后把服务从ZK上清除
                registryService.destoryAll();
            }catch (Exception ex){
            }
        }));
    }
}
